package com.ww.learn.actors

import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.channels.SendChannel
import kotlinx.coroutines.channels.actor
import kotlinx.coroutines.runBlocking

sealed class SessionMessage {
    data class GetSession(val userId: String, val response: CompletableDeferred<Session?>) : SessionMessage()
    data class UpdateSession(val session: Session) : SessionMessage() // 更新会话
    data class InvalidateSession(val userId: String) : SessionMessage() // 注销会话
    object CleanExpired : SessionMessage() // 清理过期会话
}

data class Session(
    val userId: String,
    val token: String,
    val permissions: List<String>,
    val expireTime: Long // 过期时间戳（ms）
)

// 实现Actor逻辑
fun CoroutineScope.sessionActor(): SendChannel<SessionMessage> = actor<SessionMessage>(
    context = Dispatchers.IO, // IO调度器处理可能的阻塞操作
    capacity = Channel.UNLIMITED // 会话操作频繁，允许无界队列（配合定期清理控制内存）
) {
    val sessions = mutableMapOf<String, Session>()

    // 循环处理消息
    for (msg in channel) {
        when (msg) {
            is SessionMessage.GetSession -> {
                val session = sessions[msg.userId]
                // 检查是否过期
                val validSession = session?.takeIf { it.expireTime > System.currentTimeMillis() }
                msg.response.complete(validSession)
            }

            is SessionMessage.UpdateSession -> {
                sessions[msg.session.userId] = msg.session
            }

            is SessionMessage.InvalidateSession -> {
                sessions.remove(msg.userId)
            }

            is SessionMessage.CleanExpired -> {
                val now = System.currentTimeMillis()
                sessions.values.removeAll { it.expireTime <= now }
            }
        }
    }
}

// 实际应用
class SessionService : CoroutineScope by CoroutineScope(Dispatchers.IO) {
    private val sessionActor = sessionActor()

    // 登录时创建会话
//    suspend fun createSession(userId: String): Session {
//        val session = Session(
//            userId = userId,
//            token = generateToken(),
//            permissions = getPermissions(userId),
//            expireTime = System.currentTimeMillis() + 2 * 3600 * 1000 // 2小时有效期
//        )
//        sessionActor.send(SessionMessage.UpdateSession(session))
//        return session
//    }

    // 定期清理过期会话（每30分钟一次）
//    @Scheduled(fixedRate = 30 * 60 * 1000)
    fun cleanExpiredSessions() {
        runBlocking {
            sessionActor.send(SessionMessage.CleanExpired)
        }
    }

    // 拦截器中验证会话
//    suspend fun validateToken(token: String): Boolean {
//        // 先通过token查userId
//        val userId = parseUserIdFrom(token)
//        val response = CompletableDeferred<Session?>()
//        sessionActor.send(SessionMessage.GetSession(userId, response))
//        val session = response.await()
//        return session?.token == token
//    }
}